<?php

namespace app\backend\service;

use app\common\model\CategoryModel;
use app\common\model\SourceModel;
use app\common\RootService;
use app\common\validate\CategoryValidate;

class CategoryService extends RootService
{
    /**
     * 资源标签
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function catLabel()
    {
        return ['stateLabel' => CategoryModel::$stateLabel, 'adminNames' => AdminService::adminNames(),
            'typeLabel' => CategoryModel::$typeLabel,
            'sourceList' => SourceModel::where(['state' => 0])->field(['name', 'id value'])->select()->toArray()];
    }

    /**
     * 栏目列表
     * @param array $params
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function lists(array $params)
    {
        // 资源标签
        $catLabel = $this->catLabel();
        // 数据源
        $sourceList = $this->page($this->CategoryModel($params)->order(['rank' => 'asc']));
        // 数据处理
        array_walk($sourceList['data'], function (&$row) use ($catLabel) {
            empty($row['remark']) && $row['remark'] = '--';
            $row['stateLabel'] = $catLabel['stateLabel'][$row['state']] ?? '--';
            $row['typeLabel'] = $catLabel['typeLabel'][$row['type']] ?? '--';
            $row['realName'] = $catLabel['adminNames'][$row['admin_id']]['real_name'] ?? '--';
        });
        return $sourceList;
    }

    /**
     * 添加栏目
     * @param array $params
     * @return string[]
     * @throws \app\common\RootException
     */
    public function add(array $params)
    {
        // 参数校验
        $this->verify($params, 'add');
        // 添加失败
        CategoryModel::create($this->formData($params)) || $this->errorException('添加失败');
        // 添加成功
        return ['msg' => '添加成功', 'preload' => true];
    }

    /**
     * 修改栏目
     * @param array $params
     * @return string[]
     * @throws \app\common\RootException
     */
    public function edit(array $params)
    {
        // 参数校验
        $this->verify($params, 'edit');
        // 编辑失败
        CategoryModel::update($this->formData($params)) || $this->errorException('修改失败');
        // 添加成功
        return ['msg' => '修改成功', 'preload' => true];
    }

    /**
     * 表单数据
     * @param array $params
     * @return array
     */
    protected function formData(array $params)
    {
        $postData = ['name' => $params['name'], 'title' => $params['title'], 'state' => $params['state'],
            'remark' => $params['remark'], 'rank' => $params['rank'], 'type' => $params['type']];
        // 栏目图标
        in_array($params['type'], [2]) && $postData['icon'] = $params['icon'];
        // 任务列表
        empty($params['taskData']) || $postData['task'] = $params['taskData'];
        // 新增 or 编辑
        empty($params['id']) ? $postData['admin_id'] = adminInfo('id') : $postData['id'] = $params['id'];
        // 表单数据
        return $postData;
    }

    /**
     * 数据校验
     * @param array $taskData
     * @param string $scene
     * @throws \app\common\RootException
     */
    protected function verify(array $params, string $scene)
    {
        $validate = new CategoryValidate();
        // 任务列表
        $taskData = $params['taskData'] ?? [];
        // 参数校验
        $this->validate($validate, $scene);
        // 栏目标签
        $sourceDomain = SourceModel::where(['state' => 0])->column('domain', 'id');
        // 上传图标
        in_array($params['type'], [2]) && empty($params['icon']) && $this->errorException('请上传栏目图标');
        // 采集任务校验
        empty($params['type']) && array_walk($taskData, function ($row) use ($validate, $sourceDomain) {
            $line = "采集任务第【{$row['row']}】行";
            $validate->scene('taskData')->check($row) || $this->errorException($line . $validate->getError());
            isset($sourceDomain[$row['sourceId']]) || $this->errorException($line . '数据来源无效');
            strpos($row['url'], $sourceDomain[$row['sourceId']]) == false && $this->errorException($line . '采集地址和数据来源不匹配');
        });
    }


    /**
     * 栏目详情
     * @param int $sourceId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function detail(int $sourceId)
    {
        $detail = CategoryModel::where(['id' => $sourceId])->find()->toArray();
        // 初始化任务
        empty($detail['task']) && $detail['task'] = [['row' => 1, 'sourceId' => 0, 'member' => 0, 'url' => '']];
        return $detail;
    }

    /**
     * 修改栏目排序
     * @param array $params
     * @return string[]
     * @throws \app\common\RootException
     */
    public function editRank(array $params)
    {
        $tipMsg = "{$params['title']}【栏目排序】";
        // 参数校验
        is_numeric($params['rank']) || $this->errorException("{$tipMsg}的值无效");
        // 范文校验
        ($params['rank'] > 255 || $params['rank'] < 0) && $this->errorException("{$tipMsg}取值应在0-255之间");
        // 更新失败
        CategoryModel::update(['rank' => $params['rank'], 'id' => $params['id']]) || $this->errorException("{$tipMsg}修改失败");
        // 修改成功
        return ['msg' => $tipMsg . '修改成功'];
    }

    /**
     * 栏目模型
     * @param array $params
     * @return CategoryModel
     */
    protected function CategoryModel(array $params)
    {
        // 栏目名称筛选
        empty($params['title']) || $where[] = ['title', 'like', $params['title'] . '%'];
        // 栏目类型筛选
        condition($params['type'] ?? '') && $where[] = ['type', 'in', explode(',', $params['type'])];
        // 栏目状态筛选
        condition($params['state'] ?? '') && $where[] = ['state', 'in', explode(',', $params['state'])];
        // 筛选结果
        return CategoryModel::where($where ?? []);
    }
}